package FlowGram.Application.Parser.Actions.Control;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import FlowGram.Application.Parser.FinchParser;
import FlowGram.Application.Parser.FinchParserException;
import FlowGram.Application.Parser.FinchProgramFlow;
import FlowGram.Application.Parser.Actions.Property.PropertyAction;
import FlowGram.Application.Parser.Controllers.FinchController;


/**
 * 
 * @author thackray
 *
 */
public class If extends ControlAction {

	protected PropertyAction property;
	protected FinchProgramFlow elseFlow;
	
	
	public If(FinchParser parser) {
		super(parser);
	}
	public If() {
		super();
		elseFlow = null;
//		this.elseFlow = new FinchProgramFlow();
	}
	public void setProperty(PropertyAction prop){
		this.property = prop;
	}
	public PropertyAction getProperty(){
		return this.property;
	}
//	public void setElseFlow(FinchProgramFlow flow){
//		this.elseFlow = flow;
//	}
//	public FinchProgramFlow getElseFlow(){
//		return this.elseFlow;
//	}
	public static boolean matches(String s){
		return s.matches("^if.+");
	}
	public static boolean matchesEnd(String s){
		return s.matches("^endif$");
	}
	public static boolean matchesMid(String s){
		return s.matches("^else$");
	}
	public static String syntax(){
		return "if <condition>\n\t<code>\nendif";
	}
	
	@Override
	public String toCode(int indent) {
		String code = "if "+this.property.toCode()+"\n"+this.innerFlow.toCode(indent+1)+"\n";
		if(this.elseFlow == null){
			code += this.getIndent(indent)+"endif";
		}else{
			code += this.getIndent(indent)+"else\n"+this.elseFlow.toCode(indent+1)+"\n"+this.getIndent(indent)+"endif";
		}
		return code;
	}
	@Override
	public String toHTML(String idPrefix) {
		String code = "if "+this.property.toHTML(idPrefix)+"\n"+this.innerFlow.toHTML(idPrefix)+"\n";
		if(this.elseFlow == null){
			code += "endif";
		}else{
			code += "else\n"+this.elseFlow.toHTML(idPrefix)+"\nendif";
		}
		return code;
	}

	@Override
	public void execute(FinchController controller) {
		this.ensureController(controller);
		if(this.property.getValue(controller)){
			this.innerFlow.execute();
		}else if(this.elseFlow != null){
			this.ensureController(controller, this.elseFlow);
			this.elseFlow.execute();
		}

	}

	@Override
	public String logMessage() {
		return "executing if "+this.property.toCode();
	}

	@Override
	public void parse(String statement) throws FinchParserException {
		Pattern p = Pattern.compile("^if\\s+(\\w+)$");
		Matcher matcher = p.matcher(statement);
		while(matcher.find()){
			if(matcher.group(1) != null){
				this.property = PropertyAction.findProperty(matcher.group(1));
				if(this.property == null){
					throw new FinchParserException("Unrecgonized property \""+matcher.group(1)+"\"");
					
				}
				String buffer = "";
				String line = this.parser.getNextStatement();
				while(!matchesEnd(line) && !matchesMid(line)){
					buffer += line+"\n";
					line = this.parser.getNextStatement();
				}
				FinchParser parse = new FinchParser();
				this.innerFlow = parse.Parse(buffer);
				if(matchesMid(line)){
					String elsebuffer = "";
					String elseline = this.parser.getNextStatement();
					while(!matchesEnd(elseline)){
						elsebuffer += elseline+"\n";
						elseline = this.parser.getNextStatement();
					}
					FinchParser elseparse = new FinchParser();
					this.elseFlow = elseparse.Parse(elsebuffer); 
				}
				
			}	
		}

	}
	
}
